﻿using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
using static HarmonyLib.Code;
using static UnityEngine.GraphicsBuffer;

namespace Miao
{
    public class GameCondition_EternalNight : GameCondition
    {
        #region 创建事件设置
        public IncidentCategoryDef IncidentCategory = IncidentCategoryDefOf.ThreatBig;
        //public float ThreatCount = 3;

        #endregion


        private int curColorIndex = -1;

        private int prevColorIndex = -1;

        private float curColorTransition;

        public const float MaxSunGlow = 0.5f;

        private const float Glow = 0.25f;

        private const float SkyColorStrength = 0.075f;

        private const float OverlayColorStrength = 0.025f;

        private const float BaseBrightness = 0.73f;

        private const int TransitionDurationTicks_NotPermanent = 280;

        private const int TransitionDurationTicks_Permanent = 3750;

        private static readonly Color[] Colors = new Color[8]
        {
            new Color(0f, 1f, 0f),
            new Color(0.3f, 1f, 0f),
            new Color(0f, 1f, 0.7f),
            new Color(0.3f, 1f, 0.7f),
            new Color(0f, 0.5f, 1f),
            new Color(0f, 0f, 1f),
            new Color(0.87f, 0f, 1f),
            new Color(0.75f, 0f, 1f)
        };
        //极光自由变色
        public Color CurrentColor => Color.Lerp(Colors[prevColorIndex], Colors[curColorIndex], curColorTransition);
        /// <summary>
        /// 判断时间
        /// </summary>
        private int TransitionDurationTicks
        {
            get
            {
                return 1000;
            }
        }
        /// <summary>
        /// 照亮所有地图
        /// </summary>
        private bool BrightInAllMaps
        {
            get
            {
                List<Map> maps = Find.Maps;
                for (int i = 0; i < maps.Count; i++)
                {
                    if (GenCelestial.CurCelestialSunGlow(maps[i]) <= MaxSunGlow)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        public override int TransitionTicks => 200;//剩余更新时间

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Values.Look(ref curColorIndex, "curColorIndex", 0);
            Scribe_Values.Look(ref prevColorIndex, "prevColorIndex", 0);
            Scribe_Values.Look(ref curColorTransition, "curColorTransition", 0f);
        }

        public override void Init()
        {
            base.Init();
            curColorIndex = Rand.Range(0, Colors.Length);
            prevColorIndex = curColorIndex;
            curColorTransition = 1f;
        }
        //DefaultThreatPointsNow


        public override float SkyGazeChanceFactor(Map map)
        {
            return 8f;
        }

        public override float SkyGazeJoyGainFactor(Map map)
        {
            return 5f;
        }

        public override float SkyTargetLerpFactor(Map map)
        {
            return GameConditionUtility.LerpInOutValue(this, TransitionTicks);
        }

        public override SkyTarget? SkyTarget(Map map)
        {
            Color currentColor = CurrentColor;
            return new SkyTarget(glow: 0, colorSet: new SkyColorSet(Color.Lerp(new Color(0.6f,0.6f,0.6f), currentColor, 0.1f), new Color(0.92f, 0.92f, 0.92f), new Color(0.6f, 0.6f, 0.6f), 1f), lightsourceShineSize: 1f, lightsourceShineIntensity: 0f);
        }

        private float Brightness(Map map)
        {
            return Mathf.Max(0.73f, GenCelestial.CurCelestialSunGlow(map));
        }
        const int MaxRanage = 60000 * 3;

        const float InRanage = 60000;
        const float outRanage = 120000;

        //1000*60=1天

        public override void GameConditionTick()
        {
            curColorTransition += 1f / (float)TransitionDurationTicks;
            if (curColorTransition >= 1f)
            {
                prevColorIndex = curColorIndex;
                curColorIndex = GetNewColorIndex();
                curColorTransition = 0f;

                float create = MaxRanage % TicksPassed;

                if (create > InRanage && create < outRanage)
                {
                    //执行事件更新
                    GenerateIncident(this.SingleMap);
                }
                else
                {
                    GenerateIncidentContinuousThreat(this.SingleMap);
                }
            }
        }
        

        //TryFire(item);


        private void GenerateIncident(IIncidentTarget target)
        {
            //if (Rand.MTBEventOccurs(0.05f, 60000f, 1000f))//1.5天一次。
            if (Rand.MTBEventOccurs(1.5f, 60000f, 1000f))//1.5天一次。
            {
                //Messages.Message("刷新事件(慢)", MessageTypeDefOf.NeutralEvent);
                IncidentParms parms = StorytellerUtility.DefaultParmsNow(IncidentCategory, target);
                IncidentDef incidentDef = UsableIncidentsInCategory(IncidentCategory, parms).RandomElement();
                incidentDef.Worker.TryExecute(parms);
            }
        }
        private void GenerateIncidentContinuousThreat(IIncidentTarget target)
        {
            if (Rand.MTBEventOccurs(0.3f, 60000f, 1000f))//0.3天一次
            {
                //Messages.Message("刷新事件(快)", MessageTypeDefOf.NeutralEvent);
                IncidentParms parms = StorytellerUtility.DefaultParmsNow(IncidentCategory, target);
                parms.points = parms.points * 0.8f;
                IncidentDef incidentDef = UsableIncidentsInCategory(IncidentCategory, parms).RandomElement();
                incidentDef.Worker.TryExecute(parms);
            }
        }

        protected IEnumerable<IncidentDef> UsableIncidentsInCategory(IncidentCategoryDef cat, IncidentParms parms)
        {
            IncidentParms parmsCopy = parms.ShallowCopy();
            return UsableIncidentsInCategory(cat, (IncidentDef x) => parmsCopy);
        }
        protected virtual IEnumerable<IncidentDef> UsableIncidentsInCategory(IncidentCategoryDef cat, Func<IncidentDef, IncidentParms> parmsGetter)
        {
            if (!cat.canUseAnomalyChance)
            {
                return DefDatabase<IncidentDef>.AllDefsListForReading.Where(CanUseIncident);
            }
            if (!ModsConfig.AnomalyActive || !Rand.Chance(Find.Storyteller.AnomalyIncidentChanceNow))
            {
                return Storyteller.NonAnomalyIncidents.Where(CanUseIncident);
            }
            return Storyteller.AnomalyIncidents.Where(CanUseIncident);
            bool CanUseIncident(IncidentDef incident)
            {
                if (incident.category != cat)
                {
                    return false;
                }
                return incident.Worker.CanFireNow(parmsGetter(incident));
            }
        }

        public Storyteller Storyteller
        {
            get
            {
                return Current.Game.storyteller;
            }
        }

        public List<IIncidentTarget> AllIncidentTargets
        {
            get
            {
                return Current.Game.storyteller.AllIncidentTargets;
            }
        }

        //使用Storyteller中的TryFire来启用事件


        private int GetNewColorIndex()
        {
            return (from x in Enumerable.Range(0, Colors.Length)
                    where x != curColorIndex
                    select x).RandomElement();
        }
    }
}
